#pragma once

#include <vector>
#include <string>

namespace Lijol
{

class Joystick;
class JoystickEnumerationTrigger;

class JoystickManager
{
public:
	// Pass an array of device names (such as "/dev/input/js0", "/dev/input/js1", ...) that 
	// will be monitored on a regular interval. If a device appears the corresponding Joystick
	// object will be automatically created. If it disappears it will be removed.
	// The more names to monitor, the more expensive the enumeration will be 
	JoystickManager( const std::vector<std::string>& deviceNames );

	// Same as above except that the list is constructed from a root name suffixed with 
	// a value going from 0 to numDevices. 
	JoystickManager( const char* deviceNameRoot, unsigned int numDevices );

	virtual ~JoystickManager();

	const std::vector<Joystick*>& getJoysticks() const { return mJoysticks; }

	void	update();
	void	updateEnumeration();

	class Listener
	{
	public:
		virtual void onJoystickConnected( JoystickManager* joystickManager, Joystick* joystick ) {}
		virtual void onJoystickDisconnecting( JoystickManager* joystickManager, Joystick* joystick ) {}
	};

	void	addListener( Listener* listener );
	bool	removeListener( Listener* listener );

private:
	struct JoystickIdentifier
	{
		std::string mDeviceName;	
		std::string mName;	
		bool operator==( const JoystickIdentifier& other ) const;
		bool operator!=( const JoystickIdentifier& other ) const;
	};

	static bool getJoystickIdentifier( const char* deviceName, JoystickIdentifier& identifier );
	static int getJoystickIdentifierIndex( const std::vector<JoystickIdentifier>& identifiers, const JoystickIdentifier& identifier );

	void	addJoystick( const JoystickIdentifier& identifier );

	void	removeJoystick(const JoystickIdentifier& identifier );

	static const unsigned int		mEnumerationIntervalInMs = 2000;
	JoystickEnumerationTrigger*		mEnumerationTrigger;
	std::vector<std::string>		mJoystickDeviceNames;
	std::vector<Joystick*>			mJoysticks;
	std::vector<JoystickIdentifier>	mJoystickIdentifiers;

	// Listeners
	typedef							std::vector<Listener*> Listeners; 
	Listeners						mListeners;
};

}